package com.sylingd.blog.activity

import android.Manifest
import android.app.Activity
import android.app.AlertDialog
import android.content.Intent
import android.content.pm.PackageManager
import android.graphics.drawable.Drawable
import android.os.Bundle
import android.os.Environment
import android.os.Looper
import android.support.v4.app.ActivityCompat
import android.support.v4.app.ShareCompat
import android.support.v4.content.FileProvider
import android.support.v4.view.PagerAdapter
import android.support.v7.app.AppCompatActivity
import android.support.v4.view.ViewPager
import android.view.View
import android.view.ViewGroup
import android.view.Window
import android.view.WindowManager
import android.widget.ImageView
import android.widget.ProgressBar
import android.widget.TextView
import android.widget.Toast
import com.bm.library.PhotoView
import com.bumptech.glide.Glide
import com.bumptech.glide.load.DataSource
import com.bumptech.glide.load.engine.GlideException
import com.bumptech.glide.request.RequestListener
import com.bumptech.glide.request.target.SimpleTarget
import com.bumptech.glide.request.target.Target
import com.bumptech.glide.request.transition.Transition
import com.sylingd.blog.R
import com.sylingd.blog.lib.GlideApp
import com.sylingd.blog.lib.Permission
import me.jessyan.progressmanager.ProgressListener
import me.jessyan.progressmanager.ProgressManager
import me.jessyan.progressmanager.body.ProgressInfo
import java.io.File
import java.io.FileInputStream
import java.io.FileOutputStream
import java.lang.ref.WeakReference
import java.util.*


class PhotoActivity : AppCompatActivity(), ActivityCompat.OnRequestPermissionsResultCallback {
	private lateinit var mPager: ViewPager
	private lateinit var urls: ArrayList<String>
	private var loadedPage = arrayListOf<Int>()
	private var index: Int = 0
	private var lastDownloadFile: File? = null
	private var lastFileExt = ""
	private var saveImageCount = 0

	companion object {
		fun launch(context: Activity, urls: ArrayList<String>, index: Int) {
			val intent = Intent(context, PhotoActivity::class.java)
			intent.putExtra("urls", urls)
			intent.putExtra("index", index)
			context.startActivity(intent)
		}
	}

	override fun onCreate(savedInstanceState: Bundle?) {
		super.onCreate(savedInstanceState)
		requestWindowFeature(Window.FEATURE_NO_TITLE)
		window.setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN)
		setContentView(R.layout.activity_photo)

		urls = intent.getStringArrayListExtra("urls")
		index = intent.getIntExtra("index", 0)

		val counter = findViewById<TextView>(R.id.photoCounter)
		counter.text = String.format(getString(R.string.photo_counter), index + 1, urls.size)
		mPager = findViewById(R.id.photoPager)
		mPager.pageMargin = (resources.displayMetrics.density * 15).toInt()
		mPager.adapter = Adapter()
		//监听切换事件
		mPager.addOnPageChangeListener(object: ViewPager.OnPageChangeListener {
			override fun onPageScrollStateChanged(state: Int) {
			}

			override fun onPageScrolled(position: Int, positionOffset: Float, positionOffsetPixels: Int) {
			}

			override fun onPageSelected(position: Int) {
				loadImage(position)
				//切换页面，修改计数器
				counter.text = String.format(getString(R.string.photo_counter), position + 1, urls.size)
			}
		})
		mPager.currentItem = index
	}

	//加载图片
	private fun loadImage(position: Int) {
		val v = mPager.findViewWithTag<View>(position)
		if (loadedPage.contains(position) || v == null) {
			return
		}
		val pView = v.findViewById<PhotoView>(R.id.photoView)
		//监听加载事件
		ProgressManager.getInstance().addResponseListener(urls[position], getGlideProgressListener(WeakReference(v)))
		GlideApp.with(this)
				.load(urls[position])
				.listener(getGlideListener(WeakReference(v)))
				.into(pView)
		loadedPage.add(position)
	}

	//分享图片
	private fun shareImage(url: String) {
		Glide.with(this)
				.downloadOnly()
				.load(url)
				.into(object: SimpleTarget<File>() {
					override fun onResourceReady(resource: File, transition: Transition<in File>?) {
						//使用FileProvider
						val uri = FileProvider.getUriForFile(this@PhotoActivity, "com.sylingd.blog.fileprovider", resource)
						val share = ShareCompat.IntentBuilder.from(this@PhotoActivity).setStream(uri)
						share.setType("image/*")
						val mIntent = share.intent
						mIntent.flags = Intent.FLAG_GRANT_READ_URI_PERMISSION or Intent.FLAG_GRANT_WRITE_URI_PERMISSION
						mIntent.setDataAndType(uri, "image/*")
						this@PhotoActivity.startActivity(mIntent)
					}
				})
	}


	//保存图片到本地
	private fun saveImage(url: String) {
		val ext = url.substring(url.lastIndexOf(".") + 1)
		lastFileExt = ext
		Glide.with(this)
				.downloadOnly()
				.load(url)
				.into(object: SimpleTarget<File>() {
					override fun onResourceReady(resource: File, transition: Transition<in File>?) {
						lastDownloadFile = resource
						//检查权限
						if (!Permission.check(Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
							if (Permission.isAutoRefuse(this@PhotoActivity, Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
								Permission.showDialog(this@PhotoActivity)
							} else {
								Permission.request(this@PhotoActivity, Manifest.permission.WRITE_EXTERNAL_STORAGE, 1)
							}
						} else {
							grantSuccess()
						}
					}
				})
	}

	override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray) {
		super.onRequestPermissionsResult(requestCode, permissions, grantResults)
		var isGranted = true
		var isAuto = false
		for (i in 0 until permissions.size - 1) {
			if (grantResults[i] == PackageManager.PERMISSION_DENIED) {
				isGranted = false
				if (Permission.isAutoRefuse(this, permissions[i])) {
					isAuto = true
				}
			}
		}
		if (!isGranted) {
			if (isAuto) {
				Permission.showDialog(this)
			} else {
				Permission.request(this, permissions.filterIndexed { index, _ ->
					grantResults[index] == PackageManager.PERMISSION_DENIED
				}.toTypedArray(), 1)
			}
		} else {
			grantSuccess()
		}
	}

	//授权成功
	private fun grantSuccess() {
		if (lastDownloadFile != null) {
			//有保存到本地的需求
			try {
				val env = Environment.getExternalStorageDirectory().path + "/DCIM/"
				val filename = Date().time.toString() + "-" + (saveImageCount++).toString() + "." + lastFileExt
				val ins = FileInputStream(lastDownloadFile)
				val out = FileOutputStream(env + filename)
				val buffer = ByteArray(1024)
				while (true) {
					val readed = ins.read(buffer)
					if (readed == -1) {
						break
					}
					out.write(buffer, 0, readed)
				}
				Toast.makeText(this, String.format(getString(R.string.image_saved), env + filename), Toast.LENGTH_LONG)
						.show()
				lastDownloadFile = null
				lastFileExt = ""
			} catch (e: Exception) {
				// Do nothing
			}
		}
	}

	//Glide监听器
	private fun getGlideProgressListener(mView: WeakReference<View>): ProgressListener {
		return object: ProgressListener {
			override fun onError(id: Long, e: java.lang.Exception?) {
				loadFail()
			}

			override fun onProgress(progressInfo: ProgressInfo) {
				val v = mView.get()
				v ?: return
				if (loadIsFinished(v)) return
				if (progressInfo.isFinish) {
					loadSetFinish(v)
				} else {
					loadSetPercent(v, progressInfo.percent)
				}
			}
		}
	}
	private fun getGlideListener(mView: WeakReference<View>): RequestListener<Drawable> {
		return object: RequestListener<Drawable> {
			override fun onLoadFailed(e: GlideException?, model: Any?, target: Target<Drawable>?, isFirstResource: Boolean): Boolean {
				loadFail()
				return false
			}

			override fun onResourceReady(resource: Drawable?, model: Any?, target: Target<Drawable>?, dataSource: DataSource?, isFirstResource: Boolean): Boolean {
				val v = mView.get()
				if (v != null) {
					loadSetPercent(v, 100)
					loadSetFinish(v)
				}
				return false
			}
		}
	}
	private fun loadFail() {
		if (Looper.getMainLooper() == Looper.myLooper()) {
			Toast.makeText(this,  getString(R.string.load_fail_message), Toast.LENGTH_SHORT).show()
		} else {
			mPager.post {
				Toast.makeText(this,  getString(R.string.load_fail_message), Toast.LENGTH_SHORT).show()
			}
		}
	}
	private fun loadSetPercent(v: View, percent: Int) {
		if (Looper.getMainLooper() == Looper.myLooper()) {
			v.findViewById<ProgressBar>(R.id.progressBar).progress = percent
			v.findViewById<TextView>(R.id.progressText).text = percent.toString() + "%"
		} else {
			v.post {
				v.findViewById<ProgressBar>(R.id.progressBar).progress = percent
				v.findViewById<TextView>(R.id.progressText).text = percent.toString() + "%"
			}
		}
	}
	private fun loadIsFinished(v: View): Boolean {
		return v.findViewById<ProgressBar>(R.id.progressBar).visibility == View.GONE
	}
	private fun loadSetFinish(v: View) {
		if (Looper.getMainLooper() == Looper.myLooper()) {
			v.findViewById<ProgressBar>(R.id.progressBar).visibility = View.GONE
			v.findViewById<TextView>(R.id.progressText).visibility = View.GONE
			v.findViewById<PhotoView>(R.id.photoView).visibility = View.VISIBLE
		} else {
			v.post {
				v.findViewById<ProgressBar>(R.id.progressBar).visibility = View.GONE
				v.findViewById<TextView>(R.id.progressText).visibility = View.GONE
				v.findViewById<PhotoView>(R.id.photoView).visibility = View.VISIBLE
			}
		}
	}

	inner class Adapter: PagerAdapter() {

		override fun getCount(): Int = urls.size

		override fun isViewFromObject(view: View, `object`: Any): Boolean = view === `object`

		override fun instantiateItem(container: ViewGroup, position: Int): Any {
			//父节点
			val v = layoutInflater.inflate(R.layout.item_photo, null)
			//图片节点
			val pView = v.findViewById<PhotoView>(R.id.photoView)
			pView.enable()
			pView.scaleType = ImageView.ScaleType.FIT_CENTER
			pView.setOnClickListener {
				this@PhotoActivity.finish()
			}
			pView.setOnLongClickListener {
				val options = arrayOf(getString(R.string.share), getString(R.string.save_image))
				val dialog = AlertDialog.Builder(this@PhotoActivity)
				dialog.setItems(options, { _, which ->
					when (which) {
						0 -> {
							//分享图片
							shareImage(urls[position])
						}
						1 -> {
							//保存图片到本地
							saveImage(urls[position])
						}
					}
				}).show()
				false
			}
			v.tag = position
			container.addView(v)
			if (position == mPager.currentItem) {
				loadImage(position)
			}
			return v
		}

		override fun destroyItem(container: ViewGroup, position: Int, `object`: Any) {
			loadedPage.remove(position)
			container.removeView(`object` as View)
		}
	}
}
